#pragma once
#include <string>
#include <Windows.h>
#include <osg/MatrixTransform>

class Cube : public osg::Group
{
    using inherited = osg::Group;
    using TransformPtr = osg::MatrixTransform*;
public:
    Cube();

    void front(bool ccw = true);
    void back(bool ccw = true);
    void right(bool ccw = true);
    void left(bool ccw = true);
    void up(bool ccw = true);
    void down(bool ccw = true);

    std::string writeState();
    void readState(const std::string& state);

    void reset();

    void reverse();

    bool animating() const { return !_animList.empty(); }

    float duration() const { return _duration; }
    void setDuration(float time) { _duration = time; }

    void solve();

    void handleAnimateIfNeeded(double dt);
protected:
    ~Cube();
    void build();

    struct CubeAnimateData
    {
        int face;
        bool ccw;
        float run;
        float duration;
        osg::Vec3 normal;
        TransformPtr group[9];
        osg::Matrix origin[9];
    };

    void pickAndRotateGroup(CubeAnimateData& data);
    
    float _duration;
    std::string _state;

    TransformPtr _cube[3][3][3];

    
    using AnimDataList = std::list<CubeAnimateData>;
    AnimDataList _animList;
};

